﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PerformanceAssessment.Models;
using System.Data;

namespace PerformanceAssessment.Controllers
{
    public class GoalsController : Controller
    {
        //
        // GET: /Goals/
        private PerformanceAssessmentDB db = new PerformanceAssessmentDB();

        [Authorize]
        public ActionResult Index(int assessmentId)
        {
            UserModel user = UserModel.GetCurrentUser();
            Assessment assessment = db.Assessments.Include("AssessmentPeriod").Where(a => a.ID == assessmentId).FirstOrDefault();
            if (assessment.AccessDenied(user))
                throw new AccessDeniedException();
            List<Goal> goals = db.Goals.Where(g => g.IdAssessment == assessmentId).OrderBy(g => g.ID).ToList();

            List<Goal> previousGoals = (from g in db.Goals
                         join a in db.Assessments on g.IdAssessment equals a.ID
                         where a.IdAssessmentPeriod == assessment.AssessmentPeriod.IdPreviousAssessmentPeriod
                         && a.IdEmployee == assessment.IdEmployee
                         select g).ToList();

            foreach (Goal g in goals)
            {
                g.SpecificDescription = g.SpecificDescription.Truncate(100);
                g.MeasurableDescription = g.MeasurableDescription.Truncate(100);
                g.AttainableDescription = g.AttainableDescription.Truncate(100);
                g.RelevantDescription = g.RelevantDescription.Truncate(100);
                g.TimelyDescription = g.TimelyDescription.Truncate(100);
            }

            foreach (Goal g in previousGoals)
            {
                g.SpecificDescription = g.SpecificDescription.Truncate(100);
                g.MeasurableDescription = g.MeasurableDescription.Truncate(100);
                g.AttainableDescription = g.AttainableDescription.Truncate(100);
                g.RelevantDescription = g.RelevantDescription.Truncate(100);
                g.TimelyDescription = g.TimelyDescription.Truncate(100);
            }

            ViewBag.previousGoals = previousGoals;
            ViewBag.assessmentId = assessmentId;
            return View(goals);
        }

        [Authorize]
        public ActionResult Edit(int goalId, int assessmentId)
        {
            UserModel user = UserModel.GetCurrentUser();
            Goal goal = db.Goals.Include("Assessment").Where(g => g.ID == goalId).FirstOrDefault();

            //The assessment may be the current assessment opening a previous assessment goal
            ViewBag.readOnly = false;
            if ((goal.IdAssessment != assessmentId && user.UserType != UserType.Manager) ||
                (goal.IdAssessment == assessmentId && user.UserType == UserType.Manager))
            {
                ViewBag.readOnly = true;
            }

            Assessment assessment = db.Assessments.Where(a => a.ID == assessmentId).FirstOrDefault();

            //if (user.UserType == UserType.Manager)
            //    assessment = (from a in db.Assessments
            //                   join p in db.AssessmentPeriods on a.IdAssessmentPeriod equals p.IdPreviousAssessmentPeriod
            //                   where a.IdEmployee == user.ID && p.ID == goal.Assessment.IdAssessmentPeriod
            //                   select a).FirstOrDefault();
            //else
            //    assessment = goal.Assessment;
            if (assessment.AccessDenied(user))
                throw new AccessDeniedException();

            ViewBag.assessment = assessment;
            ViewBag.userType = user.UserType;
            return View(goal);
        }

        [Authorize]
        [HttpPost]
        public ActionResult Edit(Goal goal, int assessmentId)
        {
            UserModel user = UserModel.GetCurrentUser();
            Goal saveGoal = db.Goals.Include("Assessment").Where(g => g.ID == goal.ID).FirstOrDefault();

            Assessment assessment = db.Assessments.Where(a => a.ID == assessmentId).FirstOrDefault();

            //if (user.UserType == UserType.Manager)
            //    assessment = (from a in db.Assessments
            //                  join p in db.AssessmentPeriods on a.IdAssessmentPeriod equals p.IdPreviousAssessmentPeriod
            //                  where a.IdEmployee == user.ID && p.ID == saveGoal.Assessment.IdAssessmentPeriod
            //                  select a).FirstOrDefault();
            //else
            //    assessment = saveGoal.Assessment;
            if (assessment.AccessDenied(user) || (goal.IdAssessment != assessmentId && user.UserType != UserType.Manager) ||
                (goal.IdAssessment == assessmentId && user.UserType == UserType.Manager))
                throw new AccessDeniedException();

            if (assessment.EditionAllowed(user.UserType, UserType.Employee, UserType.Manager))
            {
                if (user.UserType == UserType.Employee)
                {
                    saveGoal.SpecificDescription = goal.SpecificDescription;
                    saveGoal.MeasurableDescription = goal.MeasurableDescription;
                    saveGoal.AttainableDescription = goal.AttainableDescription;
                    saveGoal.RelevantDescription = goal.RelevantDescription;
                    saveGoal.TimelyDescription = goal.TimelyDescription;
                }
                else
                {
                    saveGoal.Achieved = goal.Achieved;
                    saveGoal.Comments = goal.Comments;
                }

                db.Entry(saveGoal).State = EntityState.Modified;
                db.SaveChanges();
            }
            else
            {
                throw new InvalidOperationException("The selected operation cannot be performed on the goal with its current assessment status.");
            }
            return RedirectToAction("Index", new { assessmentId = assessmentId });
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
